﻿/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Daidalos.Exception;

namespace Daidalos.Shaders
{

	/// <summary>
	///		Implements an abstract base class, to derive shader sets
	///		from. A shader set represents a shader effect composed of
	///		a vertex- and a fragmentshader programm, as well as
	///		their specific configuration.
	/// </summary>
	public class FontShaderSet : Shaders.ShaderSet
	{

		#region Attributes
		/// <summary>
		///		Handles to link shader properties to application data.
		/// </summary>
		Microsoft.DirectX.Direct3D.EffectHandle xOffset = null;
		Microsoft.DirectX.Direct3D.EffectHandle yOffset = null;
		Microsoft.DirectX.Direct3D.EffectHandle screenWidth = null;
		Microsoft.DirectX.Direct3D.EffectHandle screenHeight = null;
		#endregion

		#region Properties
		public float XOffset
		{
			set
			{
				if (shaderSet != null && xOffset != null)
				{
					shaderSet.SetValue(xOffset, value);
				}
			}
		}

		public float YOffset
		{
			set
			{
				if (shaderSet != null && yOffset != null)
				{
					shaderSet.SetValue(yOffset, value);
				}
			}
		}

		public float ScreenWidth
		{
			set
			{
				if (shaderSet != null && screenWidth != null)
				{
					shaderSet.SetValue(screenWidth, value);
				}
			}
		}

		public float ScreenHeight
		{
			set
			{
				if (shaderSet != null && screenHeight != null)
				{
					shaderSet.SetValue(screenHeight, value);
				}
			}
		}

		public Daidalos.Font.CharacterSet UsedCharacterSet
		{
			set
			{
				if (value != null)
				{
					shaderSet.SetValue("diffuseTexture", value.Texture.Data);
					//value.Texture.Bind(0);
				}
			}
		}
		#endregion

		#region Methods
		public FontShaderSet() : base("shaders/FontSet.fx")
		{
			// Link parameters.
			LinkParameters();
		}

		override public void Begin()
		{
			// Select the technique
			shaderSet.Technique = "Font";

			// Extract number of passes.
			int numPasses = shaderSet.Begin(FX.None);

			// Only render pass P0.
			shaderSet.BeginPass(0);
		}

		override public void End()
		{
			// End shader pass P0.
			shaderSet.EndPass();

			// End the shader passes.
			shaderSet.End();
		}

		override protected string GetInternalName()
		{
			return "FontShader";
		}

		protected override void LinkParameters()
		{
			// Invoke base's function.
			base.LinkParameters();

			// Try to link parameters.
			if (shaderSet == null)
			{
				throw new GenericException("Unable to link parameters, due to a missing shader set!");
			}
			xOffset = shaderSet.GetParameter(null, "xOffset");
			yOffset = shaderSet.GetParameter(null, "yOffset");
			screenWidth = shaderSet.GetParameter(null, "screenWidth");
			screenHeight = shaderSet.GetParameter(null, "screenHeight");
			if (xOffset == null || yOffset == null || screenWidth == null || screenHeight == null)
			{
				throw new GenericException("Failed to link at least one shader parameter!");
			}
		}
		#endregion

	}

}
